package com.fw.controller;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.fw.entity.*;
import com.fw.enums.*;
import com.fw.service.*;
import com.fw.utils.JWTUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

/***
 * @author JamesWaterman
 * @CreateDate 2021/6/19
 * @Time 13:49
 */
@RequestMapping("/slaughterhouse")
@RestController
public class SlaughterHouseController {

    @Resource
    IRkrecordService rkrecordService;
    @Resource
    IUserService userService;
    @Resource
    IPigorderService pigorderService;
    @Resource
    IPigService pigService;
    @Resource
    IWholesalersService wholesalersService;
    @Resource
    IMorderService morderService;
    @Resource
    IMorelationService morelationService;
    @Resource
    IMeatService meatService;

    /***
     * 功能描述：增加养殖场
     * 1.判断id格式
     * 2.判断用户是否存在与用户类型
     * 3.判断用户是否备案过
     * 4.插入，判断是否插入成功
     * @param raiseuid
     * @param request
     * @return
     * @throws MyException
     */
    @RequestMapping("/addRecord")
    public Result AddRecord(@RequestParam String raiseuid,
                            HttpServletRequest request) throws MyException {
        //获取用户id
        String userid = JWTUtils.getUserId(request.getHeader("token"));
        //判断输入的养殖户id是否为空
        if(raiseuid.equals(""))
            throw new MyException("养殖户id不能为空", "030102");
        Integer ruid = null;
        //将养殖户id转化为Integer类型
        try{
            ruid = Integer.parseInt(raiseuid);
        }catch (NumberFormatException e){
            throw new MyException("养殖户id格式错误", "030103");
        }

        Map<String, Object> m = new HashMap<>();
        m.put("uid", raiseuid);
        //判断用户是否存在以及用户类型是否正确
        List<User> users = userService.listByMap(m);

        if(users.isEmpty())
            throw new MyException("该用户不存在", "030101");
        if(!users.get(0).getUtype().equals(UserType.FEEDER.getValue())){
            throw new MyException("该用户不是养殖户", "030104");
        }
        //判断用户是否备案过
        m.remove("uid");
        m.put("raiseuid", raiseuid);
        m.put("killuid", userid);
        List<Rkrecord> rkrecords = rkrecordService.listByMap(m);
        if(!rkrecords.isEmpty())
            throw new MyException("该养殖户已经在本屠宰场备案过", "030106");
        //判断是否插入成功
        boolean flag = rkrecordService.save(new Rkrecord(null, ruid, Integer.parseInt(userid)));
        if(!flag)
            throw new MyException("插入数据错误，请重新尝试", "030105");

        return new Result(null, "备案成功", "000000");
    }

    /**
     * 功能描述：增加生猪订单
     * 1.判断输入数据格式
     * 2.判断用户是否存在与类型是否为养殖场
     * 3.判断用户是否在本养殖场备案
     * 4.判断填写的生猪数量范围
     * 5.插入生猪订单，判断是否插入成功
     * 6.将订单号赋给对应数量的猪
     * @param raiseuid
     * @param pigtotal
     * @param request
     * @return
     * @throws MyException
     */
    @RequestMapping("/addPigOrder")
    public Result addPigOrder(@RequestParam String raiseuid,
                              @RequestParam String pigtotal,
                              HttpServletRequest request) throws MyException {
        //数据是否为空
        if(raiseuid.equals(""))
            throw new MyException("养殖户id不能为空", "030203");
        if(pigtotal.equals(""))
            throw new MyException("生猪数量不能为空", "030207");
        Integer ruid = null, ptotal = null;
        //数据格式是否正确
        try{
            ruid = Integer.parseInt(raiseuid);
        }catch (NumberFormatException e){
            throw new MyException("养殖户id格式错误", "030204");
        }
        try{
            ptotal = Integer.parseInt(pigtotal);
            if(ptotal <= 0)
                throw new NumberFormatException();
        }catch (NumberFormatException e){
            throw new MyException("生猪数量格式错误", "030202");
        }
        //获取屠宰场用户id
        //String userid = "3";
        String userid = JWTUtils.getUserId(request.getHeader("token"));
        //查询该用户是否存在，以及该用户是否为养殖户
        Map<String, Object> m = new HashMap<>();
        m.put("uid", raiseuid);
        List<User> users = userService.listByMap(m);//找到对应user
        if(users.isEmpty())
            throw new MyException("该用户不存在", "030201");
        if(!users.get(0).getUtype().equals(UserType.FEEDER.getValue())){
            throw new MyException("该用户不是养殖户", "030205");
        }

        //判断该用户是否在此屠宰场备案过
        m.remove("uid");
        m.put("raiseuid", raiseuid);
        m.put("killuid", userid);
        List<Rkrecord> rkrecords = rkrecordService.listByMap(m);
        if(rkrecords.isEmpty())
            throw new MyException("该养殖户未在本屠宰场备案", "030106");

        //判断所需求的生猪数量是否合适
        //并获取该养殖场全部可出售生猪数量
        m.clear();
        m.put("pigraiseuid", raiseuid);
        m.put("pigkilluid", null);
        m.put("pigraisecheck", PigCheckState.PASS.getValue());
        List<Pig> pigList = pigService.listByMap(m);
        int pigNum = pigList.size();
        if(ptotal > pigNum)
            throw new MyException("该养殖场没有这么多猪，一共有" + pigNum + "头猪", "030208");

        //判断是否插入成功
        Pigorder pigorder = new Pigorder(null,
                ruid, Integer.parseInt(userid),
                ptotal, null, new Date(), null,
                null, PigOState.START.getValue(),
                null, null, null);
        boolean flag = pigorderService.save(pigorder);
        if(!flag) throw new MyException("数据插入错误，请重新尝试", "030209");
        //截取相应数量的猪
        pigList = pigList.subList(0, ptotal);
        //将生猪订单id赋给订单
        for(int i = 0; i < ptotal; i++){
            Pig pig = pigList.get(i);
            pig.setPigoid(pigorder.getPigoid());
            pig.setPigkilluid(pigorder.getPigkilluid());
        }
        flag = pigService.saveOrUpdateBatch(pigList);
        if(!flag) throw new MyException("数据插入人错误，请重新尝试", "030209");
        return new Result(null, "填写生猪订单成功", "000000");
    }

    /***
     * 功能描述：获取某屠宰场全部生猪订单
     * 1.获取全部订单
     * 2.根据订单号获取订单所包含的猪
     * @param request
     * @return
     */
    @RequestMapping("/listPigOrder")
    public Result listPigOrder(HttpServletRequest request){
        String userid = JWTUtils.getUserId(request.getHeader("token"));
        //String userid = "3";
        //获取该屠宰场所拥有的所有订单
        Map<String, Object> m = new HashMap<>();
        m.put("pigkilluid", userid);
        List<Pigorder> pigorders = pigorderService.listByMap(m);
        //每个订单的猪们
        for (Pigorder porder :
                pigorders) {
            m.remove("pigoid");
            m.put("pigoid", porder.getPigoid());
            List<Pig> pigList = pigService.listByMap(m);
            porder.setPigList(pigList);
        }
        return new Result(pigorders, "获取全部生猪订单成功", "000000");
    }


    /***
     * 功能描述：生猪订单入场
     * 1.判断生猪订单id格式
     * 2.判断该订单是否是该屠宰场的
     * 3.判断订单是否存在以及是否已经入场
     * 4.判断数量是否正确
     * 5.插入数据，判断是否插入成功
     * @param pigoid
     * @param request
     * @return
     * @throws MyException
     */
    @RequestMapping("/prepareDeath")
    public Result prepareDeath(@RequestParam String pigoid,
                               @RequestParam String arrivenum,
                               HttpServletRequest request) throws MyException {
        String userid = JWTUtils.getUserId(request.getHeader("token"));
        if(pigoid.equals(""))
            throw new MyException("订单id不能为空", "030401");
        if(arrivenum.equals(""))
            throw new MyException("生猪到达数量不能为空", "030405");
        Integer poid = null, anum = null;
        try{
            poid = Integer.parseInt(pigoid);
            anum = Integer.parseInt(arrivenum);
        }catch (NumberFormatException e){
            throw new MyException("数据格式错误", "030402");
        }
        //找到对应的订单判断是否已经入场
        Map<String, Object> m = new HashMap<>();
        m.put("pigoid", pigoid);
        List<Pigorder> pigorders = pigorderService.listByMap(m);
        List<Pig> pigList = pigService.listByMap(m);
        if(pigorders.isEmpty())
            throw new MyException("该订单不存在", "030403");
        Pigorder pigorder = pigorders.get(0);
        if(!pigorder.getPigkilluid().toString().equals(userid))
            throw new MyException("该订单不属于此屠宰场", "030407");
        if(pigorder.getPigostate().equals(PigOState.FINISH.getValue()))
            throw new MyException("该订单已入场", "030404");
        if(pigorder.getPigostate().equals(PigOState.START.getValue()))
            throw new MyException("该订单未出场", "030409");
        //判断到达数量的范围是否合理
        if(pigorder.getPigtotal() < anum || anum < 0)
            throw new MyException("生猪到达数量范围错误，该订单只有" + pigorder.getPigtotal() + "头猪", "030406");
        //更改订单状态
        List<Pig> pigList1 = pigList.subList(anum, pigList.size());
        for (Pig pig :
                pigList1) {
            pig.setPigkilluid(null);
            pig.setPigoid(null);
            LambdaUpdateWrapper<Pig> wrapper = new LambdaUpdateWrapper<>();
            wrapper.set(Pig::getPigoid, null);
            wrapper.set(Pig::getPigkilluid, null);
            wrapper.eq(Pig::getPigid, pig.getPigid());
            pigService.update(wrapper);
        }
        pigService.saveOrUpdateBatch(pigList);
        pigorder.setPigostate(PigOState.FINISH.getValue());
        pigorder.setIndate(new Date());
        pigorder.setPigarrive(anum);
        boolean flag = pigorderService.saveOrUpdate(pigorder);
        if(!flag)
            throw new MyException("插入数据错误，请重新尝试", "030408");
        return new Result(null, "该订单生猪进场成功", "000000");
    }

    /***
     * todo:后四个sql代码：
     * 功能描述：获取一些有关生猪的数据
     * 1.全部生猪，allNum
     * 2.存活且入场的生猪，allInNum
     * 3.存活且可售卖的生猪，sellableNum
     * 4.在场内但检疫未通过的生猪，noPassCheckNum
     * 5.被宰杀的生猪数量，killedNum
     * 6.正在检疫中的生猪数量，checkingNum
     * @param request
     * @return
     */
    @RequestMapping("/getAllAndCheckedNum")
    public Result getAllAndCheckedNum(HttpServletRequest request){
        String userid = JWTUtils.getUserId(request.getHeader("token"));
        JSONObject jsonObject = new JSONObject();
        //查询数据
        int allNum = pigService.count(new QueryWrapper<Pig>()
                .eq("pigkilluid", userid)
                .eq("pigstate", PigState.ALIVE.getValue()));
        Integer uid = Integer.parseInt(userid);
        int allInNum = pigService.allInPigNum(uid);
        int sellableNum = pigService.sellableNum(uid);
        int NoPassCheckNum = pigService.NoPassCheckNum(uid);
        int killedNum = pigService.killedNum(uid);
        int checkingNum = pigService.checkingNum(uid);
        //插入json
        jsonObject.put("allNum", allNum);
        jsonObject.put("allInNum", allInNum);
        jsonObject.put("sellableNum", sellableNum);
        jsonObject.put("NoPassCheckNum", NoPassCheckNum);
        jsonObject.put("killedNum", killedNum);
        jsonObject.put("checkingNum", checkingNum);
        //返回数据
        return new Result(jsonObject, "获取该屠宰场生猪信息成功", "000000");
    }

    /***
     * 功能描述：屠宰场提交检疫
     * 1.查找未被检疫过的生猪
     * 2.替换查找状态
     * 3.更新数据库相关内容
     * @param request
     * @return
     * @throws MyException
     */
    @RequestMapping("/massarceCheck")
    public Result massareCheck(HttpServletRequest request) throws MyException {
        String userid = JWTUtils.getUserId(request.getHeader("token"));
        int uid = Integer.parseInt(userid);
        //查找未被检疫过的生猪
        Map<String, Object> m = new HashMap<>();
        m.put("pigkilluid", uid);
        m.put("pigkillcheck", PigCheckState.NOTCHECK.getValue());
        List<Pig> pigList = pigService.listByMap(m);
        if(pigList.isEmpty())
            throw new MyException("该屠宰场不存在没有检疫的生猪", "030701");
        //替换数据
        for (Pig pig :
                pigList) {
            pig.setPigkillcheck(PigCheckState.CHECKING.getValue());
        }
        //更新数据库
        boolean flag = pigService.saveOrUpdateBatch(pigList);
        if(!flag)
            throw new MyException("插入数据错误，请重新尝试", "030702");
        return new Result(null, "对屠宰场内所有生猪提交检疫成功", "000000");
    }

    /***
     * 功能描述：增加猪肉订单
     * 1.判断数据格式
     * 2.查找用户
     * 3.查找符合条件的猪
     * 4.将生猪分为猪肉，插入数据库
     * 5.生成订单
     * 6.将订单与猪肉绑定
     * @param obuyuid
     * @param pignum
     * @param request
     * @return
     * @throws MyException
     */
    @RequestMapping("/addMeatOrder")
    public Result addMeatOrder(@RequestParam String obuyuid,
                               @RequestParam String pignum,
                               HttpServletRequest request) throws MyException{
        String userid = JWTUtils.getUserId(request.getHeader("token"));
        if(obuyuid.equals(""))
            throw new MyException("批发市场id不能为空", "030701");
        if(pignum.equals(""))
            throw new MyException("所需生猪数量不能为空", "030701");
        Integer buyuid = Integer.parseInt(obuyuid);
        int pnum = Integer.parseInt(pignum);
        //查找该用户
        Map<String, Object> m = new HashMap<>();
        m.put("uid", obuyuid);
        m.put("utype", UserType.WHOLESALE.getValue());
        List<User> users =  userService.listByMap(m);
        if(users.isEmpty())
            throw new MyException("该批发市场不存在", "030702");
        //查找符合条件的猪
        m.clear();
        List<Pig> pigList = pigService.listSellablePig(Integer.parseInt(userid));
        if(pigList.size() < pnum)
            throw new MyException("该屠宰场没有这么多猪，一共有" + pigList.size() + "头猪", "030703");
        pigList = pigList.subList(0, pnum);
        //生成订单
        Morder morder = new Morder(null, Integer.parseInt(userid), buyuid, OrderState.START.getValue(), null, null, null, null);
        morderService.save(morder);
        //将生猪分为猪肉，存入数据库，更新猪肉状态
        List<Meat> meatList = new ArrayList<>();
        for (Pig pig :
                pigList) {
            pig.setPigstate(PigState.DEAD.getValue());
            insertMeats(meatList, pig, buyuid, morder);
        }
        pigService.saveOrUpdateBatch(pigList);
        meatService.saveBatch(meatList);
        //将猪肉与订单绑定
        List<Morelation> morelations = new ArrayList<>();
        for (Meat meat :
                meatList) {
            morelations.add(new Morelation(null, morder.getOid(), meat.getMid()));
        }
        morelationService.saveBatch(morelations);
        return new Result(null, "填写猪肉订单成功", "000000");
    }

    /***
     * 1.查看订单是否存在，是否属于该屠宰场
     * 2.查看订单状态是否完成
     * 3.更新订单状态，存入数据库
     * @param oid
     * @param request
     * @return
     * @throws MyException
     */
    @RequestMapping("/meatOut")
    public Result meatOut(@RequestParam String oid,
                          HttpServletRequest request) throws MyException{
        String userid = JWTUtils.getUserId(request.getHeader("token"));
        if(oid.equals(""))
            throw new MyException("订单id不能为空", "030801");
        Integer orderid = Integer.parseInt(oid);
        // 查找订单
        Map<String, Object> m = new HashMap<>();
        m.put("oid", orderid);
        List<Morder> morders = morderService.listByMap(m);
        if(morders.isEmpty()) // 订单是否存在
            throw new MyException("该订单不存在", "030804");
        Morder morder = morders.get(0);
        System.out.println(morder);
        if(!morder.getOselluid().toString().equals(userid))// 订单是否属于该屠宰场
            throw new MyException("订单不属于该屠宰场", "030802");
        //检查订单状态
        if(!morder.getOstate().equals(OrderState.START.getValue()))
            throw new MyException("该订单已出场", "030803");
        //更新数据，插入数据库
        morder.setOutdate(new Date());
        morder.setOstate(OrderState.OUT.getValue());
        morderService.saveOrUpdate(morder);
        return new Result(null, "该订单成功出场", "000000");
}

    /***
     *
     * @param findtype
     * @param value
     * @param request
     * @return
     * @throws MyException
     */
    @RequestMapping("/findByKey")
    public Result findByKey(@RequestParam String findtype,
                            @RequestParam String value,
                            HttpServletRequest request) throws MyException{
        if(value.isEmpty())
            throw new MyException("value为空");
        if(findtype.isEmpty())
            throw new MyException("findType为空");
        //String userid = "3";
        String userid = JWTUtils.getUserId(request.getHeader("token"));
        Map<String, Object> m = new HashMap<>();
        JSONObject jsonObject = new JSONObject();
        Object data = null;
        m.put("pigkilluid", userid);
        if(findtype.equals("pigid")){
            m.put("pigid", value);
            List<Pig> pigList = pigService.listByMap(m);
            System.out.println(pigList);
            m.clear();
            Pigorder pigorder = new Pigorder();
            if(!pigList.isEmpty()){
                m.put("pigoid", pigList.get(0).getPigoid());
                List<Pigorder> pigorders = pigorderService.listByMap(m);
                pigorder = pigorders.get(0);
                pigorder.setPigList(pigList);
            }
            data = pigorder;
        }
        else if(findtype.equals("pigoid")){
            m.put("pigoid", value);
            List<Pigorder> pigorders = pigorderService.listByMap(m);
            if(!pigorders.isEmpty()){
                Pigorder pigorder = pigorders.get(0);
                pigorder.setPigList(pigService.listByMap(m));
                data = pigorder;
            }
        }
        else{
            throw new MyException("要查找信息的findType类型不存在");
        }
        if(data == null)
            throw new MyException("所查找信息不存在");
        return new Result(data, "返回查找数据成功", "000000");
    }

    private void insertMeats(List<Meat> meatList, Pig pig,
                             Integer buyuid, Morder morder){
        meatList.add(new Meat(null, buyuid,
                UserType.WHOLESALE.getValue(),
                "里脊", 20.0,
                pig.getPigid(), morder.getOid(),
                null, null));
        meatList.add(new Meat(null, buyuid,
                UserType.WHOLESALE.getValue(),
                "排骨", 70.0,
                pig.getPigid(), morder.getOid(),
                null, null));
        meatList.add(new Meat(null, buyuid,
                UserType.WHOLESALE.getValue(),
                "五花肉", 100.0,
                pig.getPigid(), morder.getOid(),
                null, null));
        meatList.add(new Meat(null, buyuid,
                UserType.WHOLESALE.getValue(),
                "内脏", 50.0,
                pig.getPigid(), morder.getOid(),
                null, null));
        meatList.add(new Meat(null, buyuid,
                UserType.WHOLESALE.getValue(),
                "肘子", 10.0,
                pig.getPigid(), morder.getOid(),
                null, null));
    }
}
